#include "etcder.hpp"
#include "channel.hpp"
#include "base.pb.h"
#include "file.pb.h"
#include "filer.hpp"
#include "uuid.hpp"
#include <gflags/gflags.h>
#include <thread>
#include <gtest/gtest.h>
#include <iostream>
#include <string>
#include <vector>

DEFINE_bool(log_mode, false, "程序的运行模式: true-发布模式 false-调试模式");
DEFINE_string(log_file, "", "发布模式下，制定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下，制定日志的输出等级");

DEFINE_string(etcd_host, "127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监测根目录");

DEFINE_string(service, "/service/file_service", "服务名称");

bite_im::ChannelPtr channel;
std::string single_file_id;

TEST(put_test, single_file)
{
    // 1.读取当前目录下的指定文件数据
    std::string body;
    // 2.实例化rpc客户端对象，发起rpc调用
    bool ret = bite_im::Filer::readFile("./Makefile", body);
    // 表示读取文件成功
    ASSERT_TRUE(ret);
    // 3.检测返回值是否上传成功
    auto stub = std::make_shared<bite_im::FileService_Stub>(channel.get());
    // 进行rpc调用

    // 单个文件写入
    auto req = std::make_shared<bite_im::PutSingleFileReq>();
    req->set_request_id("432248");
    req->mutable_file_data()->set_file_name("Makefile");
    req->mutable_file_data()->set_file_size(body.size());
    req->mutable_file_data()->set_file_content(body);
    auto resp = std::make_shared<bite_im::PutSingleFileRsp>();
    // 获取一个rpc操作对象
    auto cntl = std::make_shared<brpc::Controller>(); // ??
    // stub调用我们实现的服务类ipml的接口
    stub->PutSingleFile(cntl.get(), req.get(), resp.get(), nullptr);
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(resp->success());

    ASSERT_EQ(resp->file_info().file_size(), body.size());
    ASSERT_EQ(resp->file_info().file_name(), "Makefile");
    LOG_DEBUG("文件id[{}]", resp->file_info().file_id());
    single_file_id = resp->file_info().file_id();
}
TEST(get_test, single_file)
{
    // 1.先发起rpc调用获取到文件
    auto stub = std::make_shared<bite_im::FileService_Stub>(channel.get());
    auto req = std::make_shared<bite_im::GetSingleFileReq>();
    req->set_request_id("432249");
    req->set_file_id(single_file_id);
    auto resp = std::make_shared<bite_im::GetSingleFileRsp>();
    // 获取一个rpc操作对象
    auto cntl = std::make_shared<brpc::Controller>(); // ??
    ASSERT_FALSE(cntl->Failed());
    // stub调用我们实现的服务类ipml的接口
    stub->GetSingleFile(cntl.get(), req.get(), resp.get(), nullptr);
    ASSERT_TRUE(resp->success());

    ASSERT_EQ(resp->file_data().file_id(), single_file_id);
    // 将读取的文件数据resp->file_data().file_content()写入到makefile_file_download.txt中
    bool ret = bite_im::Filer::writeFile("makefile_file_download.txt", resp->file_data().file_content());
    ASSERT_TRUE(ret);
}

std::vector<std::string> multi_file_id(2);

TEST(put_test, multi_file)
{
    std::vector<std::string> body(2);
    std::vector<std::string> file_name(2);
    file_name[0] = "./base.pb.h";
    file_name[1] = "./file.pb.h";
    // 1.读取当前目录下的指定文件数据
    // 2.实例化rpc客户端对象，发起rpc调用
    bool ret = bite_im::Filer::readFile(file_name[0], body[0]);
    // 表示读取文件成功
    ASSERT_TRUE(ret);
    // 2.实例化rpc客户端对象，发起rpc调用
    ret = bite_im::Filer::readFile(file_name[1], body[1]);
    ASSERT_TRUE(ret);
    // 3.检测返回值是否上传成功
    auto stub = std::make_shared<bite_im::FileService_Stub>(channel.get());
    // 进行rpc调用

    // 单个文件写入
    auto req = std::make_shared<bite_im::PutMultiFileReq>();
    req->set_request_id("432250");
    auto file_data = req->add_file_data();

    file_data->set_file_name(file_name[0]);
    file_data->set_file_size(body[0].size());
    file_data->set_file_content(body[0]);

    file_data = req->add_file_data();

    file_data->set_file_name(file_name[1]);
    file_data->set_file_size(body[1].size());
    file_data->set_file_content(body[1]);

    auto resp = std::make_shared<bite_im::PutMultiFileRsp>();
    // 获取一个rpc操作对象
    auto cntl = std::make_shared<brpc::Controller>(); // ??
    // stub调用我们实现的服务类ipml的接口
    stub->PutMultiFile(cntl.get(), req.get(), resp.get(), nullptr);
    ASSERT_FALSE(cntl->Failed());
    ASSERT_TRUE(resp->success());

    for (int i = 0; i < resp->file_info_size(); i++)
    {
        auto info = resp->file_info(i);
        multi_file_id[i] = info.file_id();
        ASSERT_EQ(info.file_size(), body[i].size());
        ASSERT_EQ(info.file_name(), file_name[i]);

        LOG_DEBUG("文件id[{}]", info.file_id());
    }
}
TEST(get_test, muti_file)
{
    // 1.先发起rpc调用获取到文件
    auto stub = std::make_shared<bite_im::FileService_Stub>(channel.get());
    auto req = std::make_shared<bite_im::GetMultiFileReq>();
    req->set_request_id("432251");
    req->add_file_id_list(multi_file_id[0]);
    req->add_file_id_list(multi_file_id[1]);
    auto resp = std::make_shared<bite_im::GetMultiFileRsp>();
    // 获取一个rpc操作对象
    auto cntl = std::make_shared<brpc::Controller>(); // ??
    ASSERT_FALSE(cntl->Failed());
    // stub调用我们实现的服务类ipml的接口
    stub->GetMultiFile(cntl.get(), req.get(), resp.get(), nullptr);
    ASSERT_TRUE(resp->success());

    ASSERT_TRUE(resp->file_data().find(multi_file_id[0]) != resp->file_data().end());
    ASSERT_TRUE(resp->file_data().find(multi_file_id[1]) != resp->file_data().end());

    // resp->file_data()[multi_file_id[0]] 获取到fileDownloadData对象，然后找到他的此表特别甜
    auto map = resp->file_data();
    auto file_data1 = map[multi_file_id[0]];
    bool ret = bite_im::Filer::writeFile("base_file_download.txt", file_data1.file_content());
    ASSERT_TRUE(ret);
    auto file_data2 = map[multi_file_id[1]];
    ret = bite_im::Filer::writeFile("file_file2_download.txt", file_data2.file_content());
    ASSERT_TRUE(ret);
}


void online(const std::string &service_name, const std::string &service_host)
{
    LOG_INFO("服务[{}]-[{}]上线", service_name, service_host);
}
void offline(const std::string &service_name, const std::string &service_host)
{
    LOG_INFO("服务[{}]-[{}]下线", service_name, service_host);
}
int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    google::ParseCommandLineFlags(&argc, &argv, true);
    bite_im::initLogger(FLAGS_log_mode, FLAGS_log_file, FLAGS_log_level);

    // 构造Rpc服务管理对象
    auto manager = std::make_shared<bite_im::ServiceManager>();
    manager->declareService(FLAGS_service);
    // 构造服务发现对象
    auto put_cb = std::bind(&bite_im::ServiceManager::onServiceOnline, manager.get(),
                            std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&bite_im::ServiceManager::onServiceOffLine, manager.get(),
                            std::placeholders::_1, std::placeholders::_2);
    auto discoverer = std::make_shared<bite_im::Discovery>(FLAGS_base_service, FLAGS_etcd_host, put_cb, del_cb);

    // 获取服务信道
    channel = manager->choose(FLAGS_service);
    if (channel.get() == nullptr)
    {
        return -1;
    }
    // 进行Rpc调用
    // EchoService服务存根
    // auto stub = std::make_shared<bite_im::FileService_Stub>(channel.get());
    // 进行rpc调用
    return RUN_ALL_TESTS();
    // // 单个文件写入
    // {
    //     auto req = std::make_shared<bite_im::PutSingleFileReq>();
    //     auto resp = std::make_shared<bite_im::PutSingleFileRsp>();
    //     // 获取一个rpc操作对象
    //     auto cntl = std::make_shared<brpc::Controller>(); // ??
    //     // stub调用我们实现的服务类ipml的接口
    //     stub->PutSingleFile(cntl.get(), req.get(), resp.get(), nullptr);
    //     if (cntl->Failed() == true)
    //     {
    //         std::cout << "Rpc调用失败：" << cntl->ErrorText() << std::endl;
    //     }
    //     if (resp->success() == false)
    //     {
    //     }
    // }

    // // 单个文件读取
    // {
    //     auto req = std::make_shared<bite_im::GetSingleFileReq>();
    //     auto resp = std::make_shared<bite_im::GetSingleFileRsp>();
    //     // 获取一个rpc操作对象
    //     auto cntl = std::make_shared<brpc::Controller>(); // ??
    //     // stub调用我们实现的服务类ipml的接口
    //     stub->GetSingleFile(cntl.get(), req.get(), resp.get(), nullptr);
    //     if (cntl->Failed() == true)
    //     {
    //         std::cout << "Rpc调用失败：" << cntl->ErrorText() << std::endl;
    //     }
    //     if (resp->success() == false)
    //     {
    //     }
    // }

    // // 多个文件写入
    // {
    //     auto req = std::make_shared<bite_im::PutMultiFileReq>();
    //     auto resp = std::make_shared<bite_im::PutMultiFileRsp>();
    //     // 获取一个rpc操作对象
    //     auto cntl = std::make_shared<brpc::Controller>(); // ??
    //     // stub调用我们实现的服务类ipml的接口
    //     stub->PutMultiFile(cntl.get(), req.get(), resp.get(), nullptr);
    //     if (cntl->Failed() == true)
    //     {
    //         std::cout << "Rpc调用失败：" << cntl->ErrorText() << std::endl;
    //     }
    //     if (resp->success() == false)
    //     {
    //     }
    // }

    // // 多个文件读取
    // {
    //     auto req = std::make_shared<bite_im::GetMultiFileReq>();
    //     auto resp = std::make_shared<bite_im::GetMultiFileRsp>();
    //     // 获取一个rpc操作对象
    //     auto cntl = std::make_shared<brpc::Controller>(); // ??
    //     // stub调用我们实现的服务类ipml的接口
    //     stub->GetMultiFile(cntl.get(), req.get(), resp.get(), nullptr);
    //     if (cntl->Failed() == true)
    //     {
    //         std::cout << "Rpc调用失败：" << cntl->ErrorText() << std::endl;
    //     }
    //     if (resp->success() == false)
    //     {
    //     }
    // }

    // std::this_thread::sleep_for(std::chrono::seconds(10));
}
